﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;

namespace Blade.IO {
	public static class BinaryReading {
		public static BinaryReader AsBinaryReader(this Stream stream) {
			return new BinaryReader(stream);
		}

		public static byte[] ReadNullTerminatedBytes(this BinaryReader stream) {
			byte[] buffer = new byte[128];
			int pos = 0;
			do {
				if (pos == buffer.Length) {
					Array.Resize(ref buffer, buffer.Length * 2);
				}
				buffer[pos] = (byte)stream.ReadByte();
			} while (buffer[pos++] != 0);
			byte[] result = new byte[pos - 1];
			Buffer.BlockCopy(
				buffer, 0,
				result, 0,
				pos - 1
			);
			return result;
		}

		public static string ReadNullTerminatedString(this BinaryReader reader) {
			return reader.ReadNullTerminatedString(Encoding.Default);
		}
		public static string ReadNullTerminatedString(this BinaryReader reader, Encoding encoding) {
			var buffer = reader.ReadNullTerminatedBytes();
			return encoding.GetString(buffer);
		}

		public static string ReadString(this BinaryReader reader, int length) {
			return reader.ReadString(length, Encoding.Default);
		}
		public static string ReadString(this BinaryReader reader, int length, Encoding encoding) {
			if (length == 0) return string.Empty;
			var buffer = reader.ReadBytes(length);
			int index = Array.IndexOf<byte>(buffer, 0);
			return encoding.GetString(buffer, 0, index);
		}

		public static Int32 ReadCompressedInt(this BinaryReader reader) {
			byte num3;
			int num = 0;
			int num2 = 0;
			do {
				if (num2 == 35) {
					throw new NotSupportedException();
				}
				num3 = reader.ReadByte();
				num |= (num3 & 127) << num2;
				num2 += 7;
			}
			while ((num3 & 128) != 0);
			return num;
		}

		public static long Position(this BinaryReader reader) {
			return reader.BaseStream.Position;
		}
		public static long Length(this BinaryReader reader) {
			return reader.BaseStream.Length;
		}
		public static long Seek(this BinaryReader reader, long offset, SeekOrigin origin) {
			return reader.BaseStream.Seek(offset, origin);
		}

		public static BitArray ReadBitVector(this BinaryReader reader, int numBytes) {
			var bytes = reader.ReadBytes(numBytes);
			return new BitArray(bytes);
		}
	}
}
